package com.yf.notify.modules.email.providers.aliyun.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyun.dm20151123.Client;
import com.aliyun.dm20151123.models.SingleSendMailRequest;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.yf.ability.config.dto.CfgPropDTO;
import com.yf.ability.config.enums.ConfigType;
import com.yf.ability.config.enums.ProviderType;
import com.yf.ability.config.service.CfgPropService;
import com.yf.base.api.exception.ServiceException;
import com.yf.notify.modules.email.providers.aliyun.config.AliyunEmailConfig;
import com.yf.notify.modules.email.service.EmailService;
import com.yf.notify.utils.ArrayUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedHashMap;
import java.util.List;

@Log4j2
@Service("aliyunEmailService")
public class AliyunEmailServiceImpl implements EmailService {

    @Autowired
    private CfgPropService cfgPropService;


    /**
     * 发送成功代码
     */
    private static final String SUCCESS_CODE = "OK";

    /**
     * 最大发送量
     */
    private static final int MAX_TO = 100;


    @Override
    public boolean sendMail(String subject, String[] emails, String body, String templateId, LinkedHashMap<String,String> params) {

        CfgPropDTO dto = cfgPropService.detail(ConfigType.EMAIL, ProviderType.ALIYUN);
        AliyunEmailConfig conf = JSON.parseObject(dto.getData(), AliyunEmailConfig.class);

        if(conf == null || StringUtils.isBlank(conf.getAccessKeyId()) || StringUtils.isBlank(conf.getAccessKeySecret())){
            throw new ServiceException("短信配置错误，请联系管理员！");
        }

        // 最多50个收件人
        if(emails.length > MAX_TO){
            List<List<String>> list = ArrayUtils.split(emails, MAX_TO);
            boolean result = true;
            for(List<String> item: list){
                String [] subs = item.toArray(new String[0]);
                result = sendMail(conf, subject, subs, body, templateId, params);
                // 出错不发
                if(!result){
                    break;
                }
            }
            return result;
        }else{
            // 直接发送
            return sendMail(conf, subject, emails, body, templateId, params);
        }
    }


    /**
     * 发送邮件
     * @param conf
     * @param subject
     * @param emails
     * @param body
     * @param templateId
     * @param params
     * @return
     */
    private boolean sendMail(AliyunEmailConfig conf, String subject, String[] emails, String body, String templateId, LinkedHashMap<String,String> params) {

        Client client = this.createClient(conf);
        SingleSendMailRequest singleSendMailRequest = new SingleSendMailRequest()
                .setSubject(subject)
                .setAccountName(conf.getAccountName())
                .setAddressType(1)
                .setToAddress(StringUtils.join(emails, ","))
                // 注意，阿里云body则为邮件内容，不需要通过模板来创建
                .setHtmlBody(body)
                .setReplyToAddress(false);
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.singleSendMailWithOptions(singleSendMailRequest, runtime);
            return true;
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            throw new ServiceException(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            Common.assertAsString(error.message);
            throw new ServiceException(error.message);
        }
    }


    /**
     * 使用AK&SK初始化账号Client
     * @return Client
     * @throws Exception
     */
    private Client createClient(AliyunEmailConfig conf) {

        Config config = new Config()
                // 您的 AccessKey ID
                .setAccessKeyId(conf.getAccessKeyId())
                // 您的 AccessKey Secret
                .setAccessKeySecret(conf.getAccessKeySecret());
        // 访问的域名
        config.endpoint = "dm.aliyuncs.com";
        try {
            return new Client(config);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("初始化邮件发送出现问题："+e.getMessage());
        }
    }
}
